/*******************************************************************************
 * This file is part of blueprint4j www.blueprint4j.org.
 * 
 *     blueprint4j is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Lesser General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     blueprint4j is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Lesser General Public License for more details.
 * 
 *     You should have received a copy of the GNU Lesser General Public License
 *     along with blueprint4j. If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package blueprint4j.gui;

import blueprint4j.utils.*;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;

public class JColorPicker extends JDialog implements ActionListener {
	final static private int COLORS_PER_LINE = 8;
	final static private int LINE_BREAK = 6*COLORS_PER_LINE;
	final static private Dimension size = new Dimension(16 + 4 + 2, 13 + 4 + 2);
	final static private Dimension bsize = new Dimension(16 + 4, 13 + 4);
	private Color color;
	private Vector buttons = new Vector();
	private JButton custom = new JButton("Define Custom Color >>");
	private JButton ok = new JButton("OK");
	private JButton cancel = new JButton("Cancel");
	private ColorButton current = null;

	private Color[] colors =
		new Color[]{
			new Color(0xFF, 0x80, 0x80),
			new Color(0xFF, 0xFF, 0x80),
			new Color(0x80, 0xFF, 0x80),
			new Color(0x00, 0xFF, 0x80),
			new Color(0x80, 0xFF, 0xFF),
			new Color(0x00, 0x80, 0xFF),
			new Color(0xFF, 0x80, 0xC0),
			new Color(0xFF, 0x80, 0xFF),

			new Color(0xFF, 0x00, 0x00),
			new Color(0xFF, 0xFF, 0x00),
			new Color(0x80, 0xFF, 0x00),
			new Color(0x00, 0xFF, 0x40),
			new Color(0x00, 0xFF, 0x40),
			new Color(0x00, 0x80, 0xC0),
			new Color(0x80, 0x80, 0xC0),
			new Color(0xFF, 0x00, 0xFF),

			new Color(0x80, 0x40, 0x40),
			new Color(0xFF, 0x80, 0x40),
			new Color(0x00, 0xFF, 0x00),
			new Color(0x00, 0x80, 0x80),
			new Color(0x00, 0x40, 0x80),
			new Color(0x80, 0x80, 0xFF),
			new Color(0x80, 0x00, 0x40),
			new Color(0xFF, 0x00, 0x80),

			new Color(0x80, 0x00, 0x00),
			new Color(0xFF, 0x80, 0x00),
			new Color(0x00, 0x80, 0x00),
			new Color(0x00, 0x80, 0x40),
			new Color(0x00, 0x00, 0xFF),
			new Color(0x00, 0x00, 0xA0),
			new Color(0x80, 0x00, 0x80),
			new Color(0x80, 0x00, 0xFF),

			new Color(0x40, 0x00, 0x00),
			new Color(0x80, 0x40, 0x00),
			new Color(0x00, 0x40, 0x00),
			new Color(0x00, 0x40, 0x40),
			new Color(0x00, 0x00, 0x80),
			new Color(0x00, 0x00, 0x40),
			new Color(0x40, 0x00, 0x40),
			new Color(0x40, 0x00, 0x80),

			new Color(0x00, 0x00, 0x00),
			new Color(0x80, 0x80, 0x00),
			new Color(0x80, 0x80, 0x40),
			new Color(0x80, 0x80, 0x80),
			new Color(0x40, 0x80, 0x80),
			new Color(0xC0, 0xC0, 0xC0),
			new Color(0x40, 0x00, 0x40),
			new Color(0xFF, 0xFF, 0xFF),

			new Color(0xFF, 0xFF, 0xFF),
			new Color(0xEF, 0xEF, 0xEF),
			new Color(0xDF, 0xDF, 0xDF),
			new Color(0xCF, 0xCF, 0xCF),
			new Color(0xBF, 0xBF, 0xBF),
			new Color(0xAF, 0xAF, 0xAF),
			new Color(0x9F, 0x9F, 0x9F),
			new Color(0x8F, 0x8F, 0x8F),

			new Color(0x7F, 0x7F, 0x7F),
			new Color(0x6F, 0x6F, 0x6F),
			new Color(0x5F, 0x5F, 0x5F),
			new Color(0x4F, 0x4F, 0x4F),
			new Color(0x3F, 0x3F, 0x3F),
			new Color(0x2F, 0x2F, 0x2F),
			new Color(0x1F, 0x1F, 0x1F),
			new Color(0x0F, 0x0F, 0x0F)
		};

	public JColorPicker(Color p_color) {
		super();
		color = p_color;
		build();
	}


	private void build() {
		//		JPanel color_panel=new JPanel(new GridLayout(8,8));
		Box color_panel = Box.createVerticalBox();
		int pos = 0;
		JPanel top = new JPanel(new BorderLayout());
		top.add(new JLabel("Basic Colors:"), BorderLayout.WEST);
		top.add(new JPanel(), BorderLayout.CENTER);
		JPanel middle = new JPanel(new BorderLayout());
		middle.add(new JLabel("Custom Colors:"), BorderLayout.WEST);
		middle.add(new JPanel(), BorderLayout.CENTER);
		middle.add(Box.createVerticalStrut(10), BorderLayout.NORTH);

		color_panel.add(top);
		boolean definable = false;
		while (pos < colors.length) {
			switch (pos) {
			case 0:
				break;
			case LINE_BREAK:
				color_panel.add(middle);
				definable = true;
				break;
			default:
				color_panel.add(Box.createVerticalStrut(1));
				break;
			}
			Box across = Box.createHorizontalBox();
			for (int t = 0;t < COLORS_PER_LINE;t++, pos++) {
				if (t != 0) {
					across.add(Box.createHorizontalStrut(1));
				}
				JComponent button;
				if (definable){
					button = new ColorButton(pos-LINE_BREAK, color);
				} else {
					button = new ColorButton(colors[pos], color);
				}
				buttons.add(button);
				across.add(button);
			}
			color_panel.add(across);
		}

		JPanel panel = new JPanel(new BorderLayout());
		panel.add(color_panel, BorderLayout.CENTER);
		color_panel.add(Box.createVerticalStrut(10));
		// Add buttons
		JPanel pcustom=new JPanel(new BorderLayout());
		pcustom.add(custom,BorderLayout.CENTER);
		color_panel.add(pcustom);
		JPanel ok_cancel=new JPanel(new BorderLayout());
		ok_cancel.add(ok,BorderLayout.WEST);
		ok_cancel.add(cancel,BorderLayout.EAST);
		color_panel.add(ok_cancel);

		ok.addActionListener(this);
		cancel.addActionListener(this);
		custom.addActionListener(this);

		panel.add(new JPanel(), BorderLayout.NORTH);
		panel.add(new JPanel(), BorderLayout.SOUTH);
		panel.add(new JPanel(), BorderLayout.EAST);
		panel.add(new JPanel(), BorderLayout.WEST);
		panel.setBorder(BorderFactory.createRaisedBevelBorder());

		getContentPane().add(panel);
		setModal(true);
		setTitle("Color");

		setUndecorated(true);


		pack();
	}

	public Color getColor() {
		return color;
	}

	private void setColor(Color p_color) {
		color = p_color;
	}

	private void setCurrent(ColorButton p_current) {
		current = p_current;
		custom.setEnabled(current.isDefinable());
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == ok) {
			setVisible(false);
		} else if (e.getSource() == cancel) {
			setColor(null);
			setVisible(false);
		} else if (e.getSource() == custom) {
			if (current != null && current.isDefinable()) {
				Color c = JColorChooser.showDialog(null, "New Color", getBackground());
				if (c != null) {
					current.setButtonColor(c);
				}
			}
		}
	}

	class ColorButton extends JLabel implements MouseListener {
//		private JButton button = new JButton();
		private boolean definable = false;
		private String defined_name = null;

		ColorButton(int number, Color now) {
			this(Color.WHITE, now);
			defined_name = "gui.color_picker.defined_" + number;
			definable = true;
			setOpaque(true);
			Color c =
				new Color(
					Settings.getInt(defined_name + ".red", 255 - number * 16),
					Settings.getInt(defined_name + ".green", 255 - number * 16),
					Settings.getInt(defined_name + ".blue", 255 - number * 16)
				);
			setBackground(c);

			if (now.equals(c)) {
				selected();
				setCurrent(this);
			} else {
				unselected();
			}
		}

		ColorButton(Color background, Color now) {
			setOpaque(true);

			definable = false;

			setPreferredSize(size);
			setMaximumSize(size);
			setMinimumSize(size);
			setSize(size);

			if (now.equals(background)) {
				selected();
				setCurrent(this);
			} else {
				unselected();
			}

			setBackground(background);
			addMouseListener(this);
		}

		public boolean isDefinable() {
			return definable;
		}

		public void setButtonColor(Color color) {
			Settings.setInt(defined_name + ".red", color.getRed());
			Settings.setInt(defined_name + ".green", color.getGreen());
			Settings.setInt(defined_name + ".blue", color.getBlue());
			setBackground(color);
			setColor(getBackground());
			selected();
		}

		public void selected() {
			for (int t = 0;t < buttons.size();t++) {
				ColorButton button = (ColorButton)buttons.get(t);
				button.unselected();
			}
			setBorder(new CompoundBorder(LineBorder.createBlackLineBorder(), BorderFactory.createLineBorder(getBackground(), 1)));
		}

		public void unselected() {
			setBorder(
				BorderFactory.createBevelBorder(BevelBorder.LOWERED, Color.WHITE, Color.LIGHT_GRAY, Color.BLACK, Color.DARK_GRAY)
			);
		}

		@Override
		public void mouseClicked(MouseEvent e) {
			setColor(getBackground());
			setCurrent(this);
			selected();
		}

		@Override
		public void mouseEntered(MouseEvent e) {
		}

		@Override
		public void mouseExited(MouseEvent e) {
		}

		@Override
		public void mousePressed(MouseEvent e) {
		}

		@Override
		public void mouseReleased(MouseEvent e) {
		}
	}
}

